/**
    ******************************************************************************
    * @file    main.c 
    * @author  18408107475@163.com
    * @version v1.0
    * @date    2025/04/09
    * @brief   STM32F10x 多功能外设驱动库
    * @details 
    * 功能特性：
    * - LED控制（PB5, PE5）
    * - 蜂鸣器控制（PB8）
    * - 按键检测（PE4外部中断）
    * - 精确延时（us/ms/s级）
    * - 双串口通信（USART1/USART2）
    * - 格式化输出支持
    * 
    * 硬件连接：
    * - LED1: PB5（高电平灭，低电平亮）
    * - LED2: PE5（高电平灭，低电平亮）
    * - 蜂鸣器: PB8（高电平触发）
    * - 按键: PE4（下降沿触发）
    * - USART1: PA9(TX), PA10(RX)
    * - USART2: PA2(TX), PA3(RX)
    * 
    * 注意事项：
    * 1. 使用前需根据实际硬件修改引脚定义
    * 2. 系统时钟需配置为9MHz（Delay_us函数基于此频率）
    * 3. 使用printf需在工程设置中启用MicroLIB
    * 4. 中断优先级配置需根据实际需求调整
    ******************************************************************************
**/

/* 包含头文件 ----------------------------------------------------------------*/
#include "stm32f10x.h"  // STM32标准外设库（核心寄存器定义）
#include <stdio.h>      // 标准输入输出（支持printf）
#include <stdarg.h>     // 可变参数支持（用于自定义printf）

/* 函数声明 ------------------------------------------------------------------*/
// 硬件初始化
void LED_STD_Config(void);      // LED初始化（PB5/PE5）
void BEEP_STD_Config(void);     // 蜂鸣器初始化（PB8）
void KEY_STD_Config(void);      // 按键初始化（PE4外部中断）

// 精确延时
void Delay_us(uint32_t xus);    // 微秒延时（基于SysTick）
void Delay_ms(uint32_t xms);    // 毫秒延时（基于Delay_us）
void Delay_s(uint32_t xs);      // 秒延时（基于Delay_ms）

// 串口1功能
void USART1_Config(u32 baud);   // 串口1初始化（PA9/PA10）
void USART1_IRQHandler(void);   // 串口1中断服务函数
void USART1_SendByte(u8 Byte);  // 发送单字节（阻塞式）
void USART1_SendArray(u8 *Array, u16 Length); // 发送字节数组
void USART1_SendString(char *String);         // 发送字符串（以\0结尾）
void USART1_SendNumber(u32 Num, u8 Length);   // 发送数字（固定位数）
void USART1_Printf(char *format, ...);        // 自定义printf（支持格式化）

// 串口2功能
void USART2_Config(u32 baud);   // 串口2初始化（PA2/PA3）
void USART2_IRQHandler(void);   // 串口2中断服务函数
void USART2_SendByte(u8 Byte);  // 发送单字节（阻塞式）
void USART2_SendString(char *String);         // 发送字符串

/* 全局变量 ------------------------------------------------------------------*/
// 注：当前设计未使用全局变量，所有通信通过中断直接处理

/**
    ******************************************************************************
    * 函数名称：LED_STD_Config
    * 功能描述：初始化两个LED控制引脚（PB5和PE5）
    * 输入参数：无
    * 返回值  ：无
    * 详细说明：
    * 1. 配置PB5和PE5为50MHz推挽输出模式
    * 2. 初始状态：
    *    - PB5输出高电平（LED1熄灭）
    *    - PE5输出低电平（LED2点亮）
    * 3. 硬件要求：
    *    - LED阳极接3.3V，阴极接GPIO（共阳接法）
    *    - 需串联适当限流电阻（通常220Ω-1kΩ）
    * 调用示例：
    *   LED_STD_Config(); // 初始化后可通过GPIO_SetBits/ResetBits控制LED
    ******************************************************************************
**/
void LED_STD_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /* 开启GPIOB和GPIOE时钟（APB2总线） */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOE, ENABLE);

    /* 配置PB5为50MHz推挽输出 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;        // 选择引脚5
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  // 推挽输出模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 最高速度
    GPIO_Init(GPIOB, &GPIO_InitStructure);            // 应用配置

    /* 配置PE5为50MHz推挽输出（复用相同结构体） */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_Init(GPIOE, &GPIO_InitStructure);

    /* 设置初始状态 */
    GPIO_SetBits(GPIOB, GPIO_Pin_5);   // PB5高电平，LED1灭
    GPIO_SetBits(GPIOE, GPIO_Pin_5); // PE5低电平，LED2亮
}

/**
    ******************************************************************************
    * 函数名称：BEEP_STD_Config
    * 功能描述：初始化蜂鸣器控制引脚（PB8）
    * 输入参数：无
    * 返回值  ：无
    * 详细说明：
    * 1. 配置PB8为50MHz推挽输出
    * 2. 初始状态低电平（蜂鸣器关闭）
    * 3. 适用于有源蜂鸣器（高电平触发，典型工作电压3.3V）
    * 硬件连接：
    * - 蜂鸣器正极接PB8，负极接地
    * - 若使用无源蜂鸣器，需改为PWM驱动
    * 调用示例：
    *   BEEP_STD_Config();
    *   GPIO_SetBits(GPIOB, GPIO_Pin_8); // 蜂鸣器鸣响
    ******************************************************************************
**/
void BEEP_STD_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /* 开启GPIOB时钟 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    /* 配置PB8为50MHz推挽输出 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /* 初始状态：蜂鸣器关闭 */
    GPIO_ResetBits(GPIOB, GPIO_Pin_8);
}

/**
    ******************************************************************************
    * 函数名称：KEY_STD_Config
    * 功能描述：初始化按键引脚（PE4）和外部中断
    * 输入参数：无
    * 返回值  ：无
    * 详细说明：
    * 1. 配置PE4为浮空输入模式
    * 2. 设置EXTI4为下降沿触发
    * 3. 配置NVIC中断优先级为最低（0x0F）
    * 硬件要求：
    * - 按键一端接PE4，另一端接地
    * - 需外部上拉电阻（通常4.7kΩ-10kΩ）
    * - 按键按下时产生下降沿中断
    * 调用示例：
    *   KEY_STD_Config();
    *   // 需自行实现EXTI4_IRQHandler中断服务函数
    ******************************************************************************
**/
void KEY_STD_Config(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    /* 开启GPIOE时钟 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);

    /* 配置PE4为浮空输入 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOE, &GPIO_InitStructure);

    /* 开启AFIO时钟（用于外部中断线配置） */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    /* 将PE4映射到EXTI4 */
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource4);

    /* 配置EXTI4 */
    EXTI_InitStructure.EXTI_Line = EXTI_Line4;            // 选择中断线4
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  // 中断模式
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;            // 使能中断线
    EXTI_Init(&EXTI_InitStructure);                       // 应用配置

    /* 配置NVIC（嵌套向量中断控制器） */
    NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;      // 外部中断4
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; // 抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;  // 子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;       // 使能中断
    NVIC_Init(&NVIC_InitStructure);                       // 应用配置
}

/**
    ******************************************************************************
    * 函数名称：Delay_us
    * 功能描述：微秒级精确延时（基于SysTick定时器）
    * 输入参数：xus - 延时时长（0~1864134 us）
    * 返回值  ：无
    * 详细说明：
    * 1. 基于9MHz系统时钟（1us=9个时钟周期）
    * 2. 使用24位递减计数器（SysTick->LOAD）
    * 3. 最大延时受计数器位数限制（2^24/9≈1864134us）
    * 注意事项：
    * - 不适用于中断服务函数中调用
    * - 实际延时会有±3个时钟周期的误差
    * - 修改系统时钟频率需同步调整计算公式
    * 调用示例：
    *   Delay_us(100); // 精确延时100微秒
    ******************************************************************************
**/
void Delay_us(uint32_t xus)
{
    SysTick->CTRL = 0;                      // 关闭SysTick（清空控制寄存器）
    SysTick->LOAD = (9 * xus) - 1;          // 设置重装载值（9MHz时钟）
    SysTick->VAL = 0x00;                    // 清空计数器（写任何值都会清零）
    SysTick->CTRL = 0x00000001;             // 启用SysTick（使用内核时钟）
    while(!(SysTick->CTRL & 0x00010000));   // 等待计数完成（检查COUNTFLAG）
    SysTick->CTRL = 0;                      // 关闭SysTick
}

/**
    ******************************************************************************
    * 函数名称：Delay_ms
    * 功能描述：毫秒级延时（基于Delay_us）
    * 输入参数：xms - 延时时长（0~1864 ms）
    * 返回值  ：无
    * 详细说明：
    * 1. 通过循环调用Delay_us(1000)实现
    * 2. 存在函数调用开销，精度略低于Delay_us
    * 3. 最大延时受Delay_us限制
    * 调用示例：
    *   Delay_ms(500); // 延时500毫秒
    ******************************************************************************
**/
void Delay_ms(uint32_t xms)
{
    while(xms--)
    {
        Delay_us(1000);  // 累计延时
    }
}

/**
    ******************************************************************************
    * 函数名称：Delay_s
    * 功能描述：秒级延时（基于Delay_ms）
    * 输入参数：xs - 延时时长（0~1 s）
    * 返回值  ：无
    * 详细说明：
    * 1. 通过循环调用Delay_ms(1000)实现
    * 2. 适用于非精确长延时场景
    * 注意事项：
    * - 长时间阻塞式延时会影响系统实时性
    * - 需要更精确的计时建议使用硬件定时器
    * 调用示例：
    *   Delay_s(1); // 延时1秒
    ******************************************************************************
**/
void Delay_s(uint32_t xs)
{
    while(xs--)
    {
        Delay_ms(1000);  // 累计延时
    }
}

/**
    ******************************************************************************
    * 函数名称：USART1_Config
    * 功能描述：配置USART1串口通信参数
    * 输入参数：baud - 波特率（如9600,115200等）
    * 返回值  ：无
    * 详细说明：
    * 1. 使用PA9(TX)和PA10(RX)
    * 2. 通信格式：8位数据位，无校验，1位停止位
    * 3. 使能接收中断，配置为最高优先级（0）
    * 4. 硬件流控制禁用
    * 硬件连接：
    * - TX(PA9)接上位机的RX
    * - RX(PA10)接上位机的TX
    * - 需电平匹配（3.3V TTL电平）
    * 调用示例：
    *   USART1_Config(115200); // 配置为115200波特率
    ******************************************************************************
**/
void USART1_Config(u32 baud)
{
    USART_InitTypeDef USART_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    /* 开启USART1和GPIOA时钟 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

    /* 配置PA9(TX)为复用推挽输出 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  // 复用推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* 配置PA10(RX)为浮空输入 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* 配置USART1参数 */
    USART_InitStructure.USART_BaudRate = baud;       // 波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 8位数据
    USART_InitStructure.USART_StopBits = USART_StopBits_1;     // 1位停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;       // 无校验
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 收发模式
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无流控
    USART_Init(USART1, &USART_InitStructure);         // 应用配置

    /* 配置USART1中断 */
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 最高优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* 使能接收中断 */
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 接收缓冲区非空中断

    /* 使能USART1 */
    USART_Cmd(USART1, ENABLE);
}

/**
    ******************************************************************************
    * 函数名称：USART2_Config
    * 功能描述：配置USART2串口通信参数
    * 输入参数：baud - 波特率（如9600,115200等）
    * 返回值  ：无
    * 详细说明：
    * 1. 使用PA2(TX)和PA3(RX)
    * 2. 通信格式同USART1
    * 3. 中断优先级低于USART1（1）
    * 典型应用：
    * - 连接蓝牙模块
    * - 与其他设备通信
    * 调用示例：
    *   USART2_Config(9600); // 配置为9600波特率
    ******************************************************************************
**/
void USART2_Config(u32 baud)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef  NVIC_InitStructure;

    /* 开启USART2和GPIOA时钟（USART2在APB1总线） */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    /* 配置PA2(TX)为复用推挽输出 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* 配置PA3(RX)为浮空输入 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* 配置USART2参数 */
    USART_InitStructure.USART_BaudRate = baud;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_Init(USART2, &USART_InitStructure);

    /* 配置NVIC中断 */
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 次高优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* 使能接收中断 */
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

    /* 使能USART2 */
    USART_Cmd(USART2, ENABLE);
}

/**
    ******************************************************************************
    * 函数名称：USART1_IRQHandler
    * 功能描述：USART1中断服务函数（自动调用）
    * 输入参数：无
    * 返回值  ：无
    * 详细说明：
    * 1. 处理接收中断（USART_IT_RXNE）
    * 2. 实现数据回显功能（接收什么就发送什么）
    * 3. 等待发送完成标志（USART_FLAG_TC）
    * 注意事项：
    * - 中断服务函数应尽量简短
    * - 未处理其他错误中断（如溢出错误）
    * - 实际应用中建议使用缓冲区
    ******************************************************************************
**/
void USART1_IRQHandler(void)
{
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  // 检查接收中断标志
    {
        u8 data = USART_ReceiveData(USART1);  // 读取接收数据（自动清除标志位）
        USART_SendData(USART2, data);         // 回传数据
        while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET); // 等待发送完成
    }
}

/**
    ******************************************************************************
    * 函数名称：USART2_IRQHandler
    * 功能描述：USART2中断服务函数（自动调用）
    * 输入参数：无
    * 返回值  ：无
    * 详细说明：
    * 1. 处理接收中断（USART_IT_RXNE）
    * 2. 接收数据后：
    *    - 控制PB5 LED闪烁（低电平点亮）
    *    - 将数据转发到USART1
    * 典型应用：
    * - 蓝牙模块数据透传
    * - 双串口数据桥接
    ******************************************************************************
**/
void USART2_IRQHandler(void)
{
    u8 data;
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  // 检查接收中断标志
    {
        data = USART_ReceiveData(USART2);  // 读取接收数据
        USART_SendData(USART1, data);       // 数据转发到USART1
		GPIO_ResetBits(GPIOB,GPIO_Pin_5);
		Delay_ms(500);
		GPIO_SetBits(GPIOB,GPIO_Pin_5);
    }
}

/**
    ******************************************************************************
    * 函数名称：USART1_SendByte
    * 功能描述：USART1发送单个字节（阻塞式）
    * 输入参数：Byte - 要发送的字节（0x00-0xFF）
    * 返回值  ：无
    * 详细说明：
    * 1. 直接写入DR寄存器启动发送
    * 2. 等待发送缓冲区空标志（TXE）
    * 3. 最大阻塞时间：1个字节传输时间（如115200波特率约87us）
    * 调用示例：
    *   USART1_SendByte(0x41); // 发送字符'A'
    ******************************************************************************
**/
void USART1_SendByte(u8 Byte)
{
    USART_SendData(USART1, Byte);  // 写入数据寄存器启动发送
    while(!USART_GetFlagStatus(USART1, USART_FLAG_TXE)); // 等待发送完成
}

/**
    ******************************************************************************
    * 函数名称：USART2_SendByte
    * 功能描述：USART2发送单个字节（阻塞式）
    * 输入参数：Byte - 要发送的字节（0x00-0xFF）
    * 返回值  ：无
    * 实现说明：同USART1_SendByte
    ******************************************************************************
**/
void USART2_SendByte(u8 Byte)
{
    USART_SendData(USART2, Byte);
    while(!USART_GetFlagStatus(USART2, USART_FLAG_TXE));
}

/**
    ******************************************************************************
    * 函数名称：USART1_SendArray
    * 功能描述：发送字节数组
    * 输入参数：
    *   Array - 数组首地址指针
    *   Length - 数组长度（元素个数）
    * 返回值  ：无
    * 详细说明：
    * 1. 循环调用USART1_SendByte发送每个元素
    * 2. 适用于发送二进制数据块
    * 调用示例：
    *   u8 data[] = {0x01,0x02,0x03};
    *   USART1_SendArray(data, 3); // 发送3字节数据
    ******************************************************************************
**/
void USART1_SendArray(u8 *Array, u16 Length)
{
    u16 i;
    for(i = 0; i < Length; i++){
        USART1_SendByte(Array[i]);  // 逐个发送数组元素
    }
}

/**
    ******************************************************************************
    * 函数名称：USART1_SendString
    * 功能描述：发送字符串（以'\0'结尾）
    * 输入参数：String - 字符串指针
    * 返回值  ：无
    * 详细说明：
    * 1. 自动检测字符串结束符'\0'
    * 2. 支持标准C字符串格式
    * 调用示例：
    *   USART1_SendString("Hello World!"); // 发送字符串
    ******************************************************************************
**/
void USART1_SendString(char *String)
{
    u8 i;
    for(i = 0; String[i] != '\0'; i++){
        USART1_SendByte(String[i]);  // 逐个发送字符
    }
}

/**
    ******************************************************************************
    * 函数名称：USART2_SendString
    * 功能描述：USART2发送字符串（实现同USART1）
    ******************************************************************************
**/
void USART2_SendString(char *String)
{
    u8 i;
    for(i = 0; String[i] != '\0'; i++){
        USART2_SendByte(String[i]);
    }
}

/**
    ******************************************************************************
    * 函数名称：USART1_Pow
    * 功能描述：计算x的y次方（用于数字分解）
    * 输入参数：
    *   x - 底数
    *   y - 指数
    * 返回值  ：计算结果（x^y）
    * 调用示例：
    *   USART1_Pow(10,2); // 返回100
    ******************************************************************************
**/
u32 USART1_Pow(u32 x, u32 y)
{
    uint32_t Result = 1;
    while(y--)
    {
        Result *= x;  // 累乘计算幂
    }
    return Result;
}

/**
    ******************************************************************************
    * 函数名称：USART1_SendNumber
    * 功能描述：发送固定位数的数字
    * 输入参数：
    *   Num - 要发送的数字（0-99999999）
    *   Length - 显示位数（1-8）
    * 返回值  ：无
    * 详细说明：
    * 1. 从高位到低位依次分解数字
    * 2. 不足位数前面补零
    * 3. 自动转换为ASCII字符
    * 调用示例：
    *   USART1_SendNumber(123,5); // 输出"00123"
    ******************************************************************************
**/
void USART1_SendNumber(u32 Num, u8 Length)
{
    u8 i;
    for(i = 0; i < Length; i++){
        // 分解各位数字并转换为ASCII
        USART1_SendByte((Num / USART1_Pow(10, Length - i - 1) % 10) + '0');
    }
}

/**
    ******************************************************************************
    * 函数名称：fputc
    * 功能描述：重定向printf输出到串口1（MicroLIB专用）
    * 输入参数：
    *   ch - 要输出的字符
    *   f - 文件指针（未使用）
    * 返回值  ：输出的字符
    * 详细说明：
    * 1. 需在工程设置中启用MicroLIB
    * 2. 支持标准printf所有格式化功能
    * 3. 缓冲区有限，长字符串可能被截断
    ******************************************************************************
**/
int fputc(int ch, FILE *f)
{
    USART1_SendByte(ch);  // 发送字符到串口1
    return ch;
}

/**
    ******************************************************************************
    * 函数名称：USART1_Printf
    * 功能描述：自定义格式化输出函数（不依赖MicroLIB）
    * 输入参数：
    *   format - 格式化字符串
    *   ... - 可变参数列表
    * 返回值  ：无
    * 详细说明：
    * 1. 使用vsprintf实现格式化
    * 2. 最大支持100字节缓冲区
    * 3. 自动添加字符串结束符
    * 调用示例：
    *   USART1_Printf("Temp=%.1fC",25.5); // 输出"Temp=25.5C"
    ******************************************************************************
**/
void USART1_Printf(char *format, ...)
{
    char String[100];      // 格式化缓冲区
    va_list arg;           // 可变参数指针
    
    va_start(arg, format); // 初始化可变参数
    vsprintf(String, format, arg); // 格式化字符串
    va_end(arg);           // 结束可变参数
    
    USART1_SendString(String); // 发送格式化后的字符串
}

/**
    ******************************************************************************
    * 函数名称：main
    * 功能描述：主程序入口
    * 输入参数：无
    * 返回值  ：int（实际不会返回）
    * 详细说明：
    * 1. 硬件初始化流程：
    *    - LED（PB5/PE5）
    *    - 蜂鸣器（PB8）
    *    - 串口1（115200bps）
    *    - 串口2（115200bps）
    * 2. 发送蓝牙AT指令测试
    * 3. 进入主循环（可添加业务逻辑）
    * 执行状态：
    *   - PE5 LED常亮（系统运行指示）
    *   - 串口1实现数据回显
    *   - 串口2收到数据会闪烁PB5 LED
    ******************************************************************************
**/
int main(void)
{
    /* 硬件初始化 */
    LED_STD_Config();      // 初始化LED（PB5高/PE5低）
    BEEP_STD_Config();     // 初始化蜂鸣器（PB8低）
    USART1_Config(115200); // 串口1：115200bps
    USART2_Config(115200); // 串口2：115200bps
	
	/* 发送蓝牙测试指令（通过串口2） */
	//USART2_SendString("AT"); // 发送AT指令
    
    /* 主循环 */
    while(1)
    {
        
    }
}

/*************************************END OF FILE**************************************/